var amqCon = require('../util/AMQConnection');
var amqCh = require('../util/AMQChannel');
var log4js = require('log4js');
var logger = log4js.getLogger('TableManager');

function TableManager(config) {
    logger.trace("enter constructor");
    this.config = config;
    this.tables = [];
    this.tableClass = require(config.tableClass);
}

module.exports = TableManager;

TableManager.TableManager = TableManager;

TableManager.prototype.init = function (cb) {
    logger.trace('enter init');

    var that = this;
    this.amqCon = amqCon.getInstance();
    that.chReceive = new amqCh.AMQChannel(that.amqCon);
    that.chReceive.createExchange(that.config.common.tableManager.exchange, that.config.common.tableManager.key, function (obj2) {
        if (obj2 === true) {
            logger.debug('exchange ok, bind queue to this exchange');
            that.chReceive.bindQueue(that.config.common.tableManager.queue, {exclusive: false}, function (msg) {
                that.processData(JSON.parse(msg.content.toString()));
            }, true, function (obj3) {
                if (obj3 === true) {
                    logger.info('bind queue ok, waiting for messages');
                } else {
                    logger.error('cannot bind queue');
                    logger.error(obj3);
                    cb(obj3);
                }
            });
        } else {
            logger.error('cannot create exchange');
            logger.error(obj2);
            cb(obj2);
        }
    });
};

TableManager.prototype.processData = function (msg) {
    logger.trace('enter processData');
    var data = msg;
    var that = this;
    switch (data.action) {
        case 'find_table':
            logger.info('create new table');
            var name = this.getFreeTable();
            var tb = new this.tableClass.Table(name + 1, this.config.common);
            this.insertArray(tb, name);
            tb.init(function (result) {
                var chPlayer = new amqCh.AMQChannel(that.amqCon);
                chPlayer.createExchange(that.config.common.players.exchange, data.key, function (obj4) {
                    if (obj4 === true) {
                        logger.info('created channel to player: ' + data.player);
                        chPlayer.sendMessage({
                            action: 'find_table',
                            table: name + 1,
                            tableKey: tb.key
                        });
                        chPlayer.disconnect();
                    } else {
                        logger.error('cannot create channel to player: ' + data.player);
                        logger.error(obj4);
                        // fatal error, need to retry
                    }
                });
            });
            break;
        case 'delete_table':
            this.deleteTable(data.tableID);
            break;
        default:
            break;
    }
};

TableManager.prototype.getFreeTable = function () {
    logger.trace('enter getFreeTable');

    var i = 0;
    for (i = 0; i < this.tables.length; i += 1) {
        if (this.tables[i] === null) {
            break;
        }
    }

    return i;
};

TableManager.prototype.insertArray = function (table, index) {
    if (index === 0 || index === this.tables.length) {
        this.tables.push(table);
    } else {
        this.tables[index] = table;
    }
};

TableManager.prototype.deleteTable = function (id) {
    logger.trace('enter deleteTable');
    var i;

    for (i = 0; i < this.tables.length; i += 1) {
        if (this.tables[i].id === id) {
            logger.info('delete table id ' + id + ', at: ' + i);
            //logger.debug(this.tables[i]);
            this.tables.splice(i, 1);
            break;
        }
    }
};
